<?php

namespace App\Console\Commands;

use App\Enums\ProductStatus;
use App\Models\Product;
use App\Models\ProductToken;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class ProductSyncCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'product:sync';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '从资产发行平台同步资产数据到商品表';

    /**
     * Create a new command instance.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $towDaysAgo = now()->subDays(2);
        // 查询2天前同步的最大资产ID
        $checkPoint = Product::query()->where('created_at', '<', $towDaysAgo)->select(\DB::raw('max(asset_id) as asset_id'))->value('asset_id');
        // 查询2天内同步的资产ID列表
        $recentSyncedAssetIds = Product::query()->where('created_at', '>=', $towDaysAgo)->select(['asset_id'])->get()->pluck('asset_id');

        // 查询资产
        $assets = \DB::connection('mysql_pub')->table('assets')
            ->join('register', 'register.id', '=', 'assets.create_by')
            ->where('assets.assets_state', 'assets_publish')   // 已发行的作品
            ->where('assets.id', '>', $checkPoint)
            ->whereNotIn('assets.id', $recentSyncedAssetIds)            // 跳过已同步的资产
            ->where('assets.issue_type', 3)     // 发行类型: 资产批量发行
            ->select([
                'assets.id',                // 资产ID
                'assets.logo_url',          // 封面图
                'assets.enterprise_name',   // 发行方名称
                'assets.rights',            // 许可权利类型
                'assets.enterprise_abbreviation',       // 商品名称
                'assets.goods_name',        // 作品名称
                'assets.contract_address',  // 合约地址
                'assets.public_hash',       // 公示Hash
                'assets.issue_count',       // 发行数量
                'assets.single_price',      // 发行单价
                'register.mobile',          // 创建者手机号
            ])
            ->orderByDesc('assets.id')
            ->limit(10) // 每次最多同步10条
            ->get();

        foreach ($assets->reverse() as $asset) {
            if (Product::query()->where('asset_id', $asset->id)->count() > 0) {
                continue;
            }
            $product = new Product();
            $product->asset_id = $asset->id;
            $product->issuer = Str::substr($asset->enterprise_name, 0, 32);
            $product->hold_rights = $this->parseHoldRights($asset->rights);
            $product->logo_url = str_replace('http://copyright-securitization.obs.cn-north-4.myhuaweicloud.com', 'https://cdn.banquan520.com', $asset->logo_url);
            $product->name = Str::substr($asset->enterprise_abbreviation, 0, 64);
            $product->public_hash = $asset->public_hash;
            $product->contract_address = $asset->contract_address ?: 'empty_contract_address_' . $asset->id;
            $product->issue_count = intval($asset->issue_count);
            $product->left_count = $product->issue_count;
            $product->price = toFen($asset->single_price);
            $product->publisher_account = $asset->mobile;
            $product->status = ProductStatus::INIT;

            $this->output->writeln(sprintf('[%s] PRODUCT_SYNC: 商品【%s】同步开始，发行数量: %s', now()->toDateTimeString(), $product->name, $product->issue_count));
            \DB::transaction(function () use ($product) {
                $product->save();
                $offset = 0;
                $limit = 1000;
                while (true) {
                    // 查询tokens
                    $tokenIds = \DB::connection('mysql_pub')->table('assets_batch_tokens')
                        ->select(['token_id'])
                        ->whereNotNull('token_id')
                        ->where('assets_id', $product->asset_id)
                        ->offset($offset)->limit($limit)
                        ->pluck('token_id');
                    if (0 === count($tokenIds)) {
                        break;
                    }
                    $tokenRows = [];
                    foreach ($tokenIds as $tokenId) {
                        $tokenRows[] = [
                            'created_at' => now(),
                            'updated_at' => now(),
                            'product_id' => $product->id,
                            'token_id' => $tokenId,
                        ];
                    }
                    ProductToken::insert($tokenRows);
                    $offset += $limit;
                    $this->output->write('.');
                }
            });
            $this->output->writeln('');
        }

        return Command::SUCCESS;
    }

    /** 许可权利类型转换 */
    private function parseHoldRights($rights)
    {
        $map = [
            'copy' => '复制权',
            'issue' => '发行权',
            'rent' => '出租权',
            'exhibition' => '展览',
            'perform' => '表演权',
            'project' => '放映权',
            'broadcast' => '广播权',
            'propagate' => '信息网络传播权',
            'record' => '摄制权',
            'adaption' => '改编权',
            'translate' => '翻译权',
            'assembly' => '汇编权',
            'other' => '其它权利',
        ];
        $rightsKeys = explode(',', $rights);
        $parsedRights = Arr::only($map, $rightsKeys);

        return implode(',', $parsedRights);
    }
}
